// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	11/13/2013 11:09:01 AM				
// -----------------------------

#include "Sound.h"
#include "AudioManager.h"
#include "SoundChannel.h"

Sound::Sound(FMOD::Sound* lpSound, AudioManager* lpAudioManager)
	: m_lpSound(lpSound)
	, m_lpAudioManager(lpAudioManager)
	, m_lpSoundChannel(nullptr)
	, m_bPaused(false)
{
}

Sound::~Sound()
{
	//m_lpSound->release();
	delete m_lpSoundChannel;
}

SoundChannel* Sound::Play(bool bLoop, float fVolume)
{
	if (m_bPaused && m_lpSoundChannel)
	{
		m_bPaused = false;
		m_lpSoundChannel->m_lpSoundChannel->setPaused(false);
	}
	else
	{
		FMOD::Channel* lpSoundChannel = nullptr;
		FMOD_RESULT r = m_lpAudioManager->m_lpSystem->playSound(FMOD_CHANNEL_FREE, m_lpSound, false, &lpSoundChannel);
		UINT uMode = 0;
		if (bLoop)
			uMode = FMOD_LOOP_NORMAL;
		else
		{
			uMode = FMOD_LOOP_OFF;
			lpSoundChannel->setLoopCount(0);
			m_lpSound->setLoopCount(0);
		}
		lpSoundChannel->setMode(uMode);
		m_lpSound->setMode(uMode);
		if (r != FMOD_OK)
			return nullptr;
		if (m_lpSoundChannel)
			delete m_lpSoundChannel;
		m_lpSoundChannel = new SoundChannel(lpSoundChannel);
	}

	m_lpSoundChannel->m_lpSoundChannel->setVolume(fVolume);
	return m_lpSoundChannel;
}
void Sound::Pause()
{
	if (m_lpSoundChannel)
		m_lpSoundChannel->m_lpSoundChannel->setPaused(true);
	m_bPaused = true;
}
void Sound::Stop()
{
	if(m_lpSoundChannel)
		m_lpSoundChannel->m_lpSoundChannel->stop();
	delete m_lpSoundChannel;
	m_lpSoundChannel = nullptr;
}

void Sound::SkipForward(float fTimeSkip)
{
	UINT uPosition = GetPosition();
	UINT uOffset = (UINT) (fTimeSkip * 1000.0f);
	UINT uNewPosition = uPosition + uOffset;
	uNewPosition = Math::Max((UInt32) 0,uNewPosition);
	uNewPosition = Math::Min(uNewPosition,GetLength());
	SetPosition(uNewPosition);
}
void Sound::SkipBackwards(float fTimeSkip)
{
	UINT uPosition = GetPosition();
	UINT uOffset = (UINT) (fTimeSkip * 1000.0f);
	UINT uNewPosition = uPosition - uOffset;
	uNewPosition = Math::Max((UInt32) 0,uNewPosition);
	uNewPosition = Math::Min(uNewPosition,GetLength());
	SetPosition(uNewPosition);
}

void Sound::SetPosition(UINT uPosition)
{
	if(m_lpSoundChannel)
		m_lpSoundChannel->m_lpSoundChannel->setPosition(uPosition,FMOD_TIMEUNIT_MS);
}
void Sound::SetVolume(float Volume)
{
	if (m_lpSoundChannel)
		m_lpSoundChannel->m_lpSoundChannel->setVolume(Math::Clamp(Volume));
}

UINT Sound::GetLength() const
{
	UINT uLength = 0;
	m_lpSound->getLength(&uLength,FMOD_TIMEUNIT_MS);
	return uLength;
}
UINT Sound::GetPosition() const
{
	if(m_lpSoundChannel)
	{
		UINT uPosition = 0;
		m_lpSoundChannel->m_lpSoundChannel->getPosition(&uPosition,FMOD_TIMEUNIT_MS);
		return uPosition;
	}
	return 0;
}

bool Sound::IsPlaying() const
{
	if(!m_lpSoundChannel)
		return false;
	bool bIsPlaying = false;
	m_lpSoundChannel->m_lpSoundChannel->isPlaying(&bIsPlaying);
	return bIsPlaying;
}
SoundChannel* Sound::GetSoundChannel() const
{
	return m_lpSoundChannel;
}